#!/usr/bin/env python2
#-*- coding: utf-8 -*-

"""
Created on 20160328
"""

import os
import sys
import base64
import json
import logging
import logging.handlers
import time
import web
import traceback
import threading
import signal
import socket

from subprocess import Popen, PIPE

import Umpweb
from Umpweb.common import log, config
from Umpweb.common import utils
from Umpweb.db import api as db_api 
from Umpweb.common.wsgilog import WsgiLog, LogStdout

from Umpweb.urls import urls
from Umpweb.base import init_app, _init_session, StaticMiddleware
import defs


#render._lookup.globals.update(_ = _)
#render._lookup.globals.update(session=session)

app = init_app(urls)
session = _init_session(app)

pwd_path = os.path.dirname(os.path.realpath(__file__))
os.chdir(pwd_path)

LOG = log.get_log("Ump.main")
H_LOG = log.get_history_log()

def session_hook():
    web.ctx.session = session
    web.config._session = session

def history_hook():
    '''
    会把web.ctx中的相关内容记录到日志中
    web.ctx =
     ['status', 'realhome', 'homedomain', 'protocol', 'app_stack', 
     'db_session', 'ip', 'fullpath', 'headers', 'host', 'session', 
     'environ', 'env', 'home', 'homepath', 'output', 
     'path', 'query', 'method']
    '''
    path_skips = ['/ear/notice:GET','/help/register_submit:POST',
            '/oem_manager:POST']

    path = web.ctx.env.get('PATH_INFO')
    method = web.ctx.env.get('REQUEST_METHOD')
    flag = '%s:%s'%(path, method)

    if flag in path_skips:
        return ''

    record = []
    H_LOG.info(str(web.ctx.env))
    record.append(web.ctx.env.get('REMOTE_ADDR'))
    record.append(web.ctx.env.get('REMOTE_PORT'))
    record.append(web.ctx.env.get('REQUEST_METHOD'))
    record.append(web.ctx.env.get('PATH_INFO'))
    record.append(str(web.input()))
    http_info_str = " ".join(record)
    H_LOG.info(http_info_str)

class ParamError(Exception):
    pass

class Server(object):

    hostname = os.popen('hostname').read().strip('\n')
    CORRELATION_ID = "correlationId"
    REPLY_TO = "replyTo"
    NO_NEED_REPLY_MSG = 'noReply'

    def __init__(self):
        self.uuid = utils.uuid4()
        self.reply_ui_port = config.ui_consumer_port
        self.controller_consumer_port = config.controller_port
        self.controller_consumer_port = config.controller_port
        self.controller_server_ip = config.controller_server_ip


    @utils.retry()
    def send(self, msg_str, url="/fusionstor_pipe", method="POST"):
        msg = msg_str
        if not isinstance(msg_str,dict):
            msg = json.loads(msg_str)
        
        if len(msg.keys()) != 1:
            raise ParamError(u'消息格式必须是只有一个键的字典')
        
        msg_name = msg.keys()[0]
        msg_body = msg.values()[0]
        mid = msg_body['id'] = utils.uuid4()
        
        headers = {
            self.CORRELATION_ID: mid,
            self.REPLY_TO: self.reply_ui_port,
            self.NO_NEED_REPLY_MSG: 'false'
        }
        msg_body['ui_info'] = headers
        params = msg_body.get('params', {})
        
        if not params.get('username'): 
            params['username'] = web.config._session.user.name
            params['op_username'] = web.config._session.user.name

        if not params.get('op_user_id'): 
            params['op_user_id'] = web.config._session.user.id
        
        if not msg_name == "QueryDB":
            LOG.info("send message %s" % msg)
        
        token = web.config._session.user.token or web.ctx.env.get('HTTP_TOKEN')
        return utils._exec_http(msg_str, host=self.controller_server_ip, 
            port=self.controller_consumer_port, url=url, method=method, token=token)


    def api_sync_call(self, msg_str, url='/fusionstor_pipe', method='POST'):
        try:
            reply = self.send(msg_str, url=url, method=method)
            return json.dumps(reply)
        except Exception as e:
            traceback.print_exc()
            LOG.debug(utils.get_exception_stacktrace())
            return utils.exception2json(e)

class WLog(WsgiLog):

    def __init__(self, application):
        WsgiLog.__init__(self,
                        application,
                        logformat = '%(asctime)s-%(message)s',
                        tofile = True,
                        toprint = True,
                        file = '%s/log/ump/dashboard_server.log' % utils.install_path,
                        MAXBYTES = 1024000 * 20,
                        BACKUPCOUNT = 5
                        )
        sys.stdout = LogStdout(self.logger, logging.INFO)
        sys.stderr = LogStdout(self.logger, logging.ERROR)

def delete_session():
    session_dir = os.path.join(os.path.dirname(os.path.realpath(Umpweb.__file__)), 'sessions')
    os.system('rm -rf %s/*' % session_dir)

def sendmessage(message, host='127.0.0.1', port=27905):
    try:
        message = str(message)
        s = socket.socket()  
        s.connect((host, port))  
        s.send(message)
        s.close()
    except Exception,e:
        LOG.info('%s' % (e))
        pass

def send_message():
    time.sleep(2)
    sendmessage('start')

def main(port, is_WLOG=True):
    delete_session()

    server = Server()
    web.config._server = server

    app.add_processor(web.loadhook(session_hook))
    app.add_processor(web.loadhook(history_hook))


    port = port or defs.UI_PORT
    if defs.PRODUCT_NAME == 'fusionnas':
        os.system('fusionnas-controller-server --stop;fusionnas-controller-server --start')
    else:
        os.system('ump-controller-server --stop;ump-controller-server --start')
    LOG.info("http://0.0.0.0:%s/" % port)
#    send_message()
    port = int(port)
    if is_WLOG:
        app.run(port, StaticMiddleware, WLog)
    else: 
        app.run(port, StaticMiddleware)

if __name__ == "__main__":
    port = 8080
    if len(sys.argv) > 1:
        port = sys.argv[-1] 
    assert isinstance(port, int) or port.isdigit(), "port is require Integer"
    main(port=int(port))

